package fun.eliauk.treedemo.utils.encrypt;

import cn.hutool.crypto.asymmetric.AsymmetricAlgorithm;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.stereotype.Service;

import java.security.PublicKey;

@ConditionalOnProperty(value = "qqzj.encrypt", havingValue = "rsa",matchIfMissing = true)
@Service
@Slf4j
public class RSAEncryptService implements EncryptService{
    @Override
    public String encrypt(String content) {
        return null;
    }

    @Override
    public String decrypt(String content) {
        return null;
    }


    @Value("${rsa.pub-key}")
    private String publicKey;

    @Value("${rsa.pri-key}")
    private String privateKey;


    // 加密成为Base64编码的字符串 ----公钥加密
    public  String rsaPubEncrypt(String content){
        RSA rsa = new RSA(privateKey,publicKey);
        return rsa.encryptBase64(content,KeyType.PublicKey);
    }

    //加密成为Base64编码的字符串   ----私钥加密
    public  String rsaPriEncrypt(String content){
        RSA rsa = new RSA(privateKey,publicKey);
        return rsa.encryptBase64(content,KeyType.PrivateKey);
    }

    //把Base编码的字符串密文解密成为明文 ----公钥解密
    public  String rsaPubDecrypt(String content){
        RSA rsa = new RSA(privateKey,publicKey);
        return rsa.decryptStr(content,KeyType.PublicKey);
    }

    // 把Base64编码的字符串密文解密成为明文 ---- 私钥解密
    public  String rsaPriDecrypt(String content){
        RSA rsa = new RSA(privateKey,publicKey);
        return rsa.decryptStr(content,KeyType.PrivateKey);
    }

    /**
     * RSA 算法是一种非对称加密算法， 有公钥私钥之分
     * 非对称加密：
     * 由公钥加密的密文 只有相对应的密钥能够解密成为明文
     * 由密钥加密的密文 只有相对应的公钥能够解密成为明文
     * 公钥对 同一段 明文 加密的结果都是不同的 但密钥解密出来的明文却都是同样的   ----提高了安全性
     * 密钥对 同一段 明文 加密的结果是相同的。
     *
     *  实际运用中， 公钥会公开给所有人，有了公钥就能解开私钥加密的数据，那么这样加密还有什么意义呢？
     *  其实在非对称加密算法中光对 数据加密这个功能而言：   公钥是用来加密的，私钥是用来解密的（保密性）
     *  而公钥 解密 私钥加密的密文 是来干什么的呢 ：
     *  所有人都能得到这个公钥，而且这个公钥只能解密向对应的 私钥的密文 。那么发这条密文的人一定是 私钥持有者 （验证性）
     *  那么就相当于所有人都在监督这个 密钥持有人 。
     *  大家都能看到这个密钥持有人发送的密文 ，发密文的人不能说他没发过，因为只有他有私钥，(不可抵赖性)这一点跟区块链的防篡改性很相似
     *  在很多时候，私钥持有者可能并不只是发送一段密文，可能还带有一些操作（比如说修改商品金额，开除员工这样的操作）
     *  那这样的操作应该是十分谨慎的，不能说你修改了然后出事了，你不认账说不是我删的，不是我改的，我也不知道是谁改的，可能网络有问题啥的
     *  那不可能，因为技术上实现了只有你有私钥，只有你才能修改、删除。别人都不可能执行这个操作。而且大家都能看到是你操作的，你就不能够赖账了
     *  当然这只是技术上的实现。不过 不管多严密的技术，哪能防过人心呢
     *
     *
     *  现在回过头思考一个问题，为什么 公钥对同一段密文多次加密，每次的加密结果都不一样呢？
     *  非对称加密算法通常使用一种称为填充（padding）的技术来增加数据的安全性和随机性。
     *  填充是在明文加密之前对数据进行处理的过程，以确保每次加密的结果都是不同的。
     *  所以每一次加密其实加密之前的明文就不同，所以得到的密文就不同。
     *
     *  那为什么每次用私钥钥都能解密出的结果都一样呢？
     *  私钥解密的过程是确定性的，不受填充和随机性的影响。私钥解密算法会使用私钥的数学运算逆过程，将密文转换回原始的明文。
     *  由于私钥是唯一的，并且与公钥是一对密钥，所以每次使用相同的私钥解密相同的密文，都会得到相同的明文结果。
     *  意思就是说 私钥是知道公钥使用了什么样的填充算法的，不管
     *
     *
     */




    public static void main(String[] args) {
        String publicKey =
                "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmiLZVrqjJgu5ZktVo8Xq\n" +
                "I9Q1JpcVk4LNWQnx3jVKhAP7lOdB6qNxkSdB9lBmGxf3w447m2PkHhdigeaB2o48\n" +
                "xvyd95Kg09HH5FY/stZx5vlKTWf7WR1QpuLcoaJOKiJB7oNYSYwds2P4qgWQXSGq\n" +
                "8RF74EIOzugy56R0tHq+JYr0xCrYjxYrKYgRaA/8gnDCcytYhhzOBWfZLS6kKIvy\n" +
                "j+QBTz3Z1LhI4I3WDvw90Hlamc4yXIWZACHwGqQiDsn76FxRiLdICbYWk6XmnDS0\n" +
                "JCsRBojGQBW26GXujqPPFhW4KyplSOoQ/cdJxzwvZs7HCiyzZt1xTv/p/+fcyt40\n" +
                "AQIDAQAB";
        String privateKey =
                "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCaItlWuqMmC7lm\n" +
                "S1Wjxeoj1DUmlxWTgs1ZCfHeNUqEA/uU50Hqo3GRJ0H2UGYbF/fDjjubY+QeF2KB\n" +
                "5oHajjzG/J33kqDT0cfkVj+y1nHm+UpNZ/tZHVCm4tyhok4qIkHug1hJjB2zY/iq\n" +
                "BZBdIarxEXvgQg7O6DLnpHS0er4livTEKtiPFispiBFoD/yCcMJzK1iGHM4FZ9kt\n" +
                "LqQoi/KP5AFPPdnUuEjgjdYO/D3QeVqZzjJchZkAIfAapCIOyfvoXFGIt0gJthaT\n" +
                "peacNLQkKxEGiMZAFbboZe6Oo88WFbgrKmVI6hD9x0nHPC9mzscKLLNm3XFO/+n/\n" +
                "59zK3jQBAgMBAAECggEBAJjGPeHG7/q/2C3aMbI4cxC8P0pWqh4hoePFBaUX8RnU\n" +
                "0MIQTbeB9QjIforjubDVGtEL42zrn6lryEm07bRxEzCwJurCvQH2hkh+bHiYMSGc\n" +
                "qdb7X5g+hDhF2CWlOBBvECaWrSWI6c9rIYd0KFkHC+YRTFVFZGQUppAO41YX6uxN\n" +
                "utc4JuSobwajZz0uD97fmjJDPRPCnF9BCpQgpyFEnyAfZr1rw4qfkbQ22DP/suqQ\n" +
                "EDZ+q5J/NjQYyMpCQcwQMBVfqTwIqRbO7w+hA2DUgmuMvIbme2j+qNVxw8J7qM5z\n" +
                "XcMprQaFZBKFIK36RPzrLdgQVBYM5xMPZ8MEpXq2DIECgYEAy0Jjyzbt7BRm9CoE\n" +
                "EkcYA6F7xeZ5wC46a6ZRjER5DWgzSgiKdSYiGceUVjIhFukV1XniCnxyfXNZ0A4r\n" +
                "kJjh4A6FV+B9GPQTP2ddkNQaj3t6EaQ1sxfMv26mxedoC+WgEBqeWfcggbAMaAPj\n" +
                "1Y0zbqCZn5KD8yQQA0FLkkDxFQkCgYEAwiFsgs6OPa7l3ZfBKGTCxyah7nwLAGb4\n" +
                "rJYSMohN8hYkkf2yDrQTd6L4hTwkY1eV3AGGpJyJ1uyHUNWTlGQ0J2Zae/jCHN0H\n" +
                "AXUw383jUaAok0qilFqCSxRnwBjrBZpMcs/IYVvZ3YZtsksP0yJBNCBns78IX+Se\n" +
                "qH2hKw16nTkCgYEAmHLI6mfedwyuUz8YIqVT65U4givk8TE6+/aYfz30FQwsO8DA\n" +
                "KDFbrj40kZmzm71idOSflwHT1SepGxUls6QW9beuZ0SmTwrxTMK4OKH88dTIr2ac\n" +
                "KCEXnhTd3N08+n9VV/6++fcSWHK0O2d/gHIRO04VKsv3T2ui3u4gQieXKhECgYBP\n" +
                "Bjgbz2WLqoSb/ch9XvcDBrDoWcpIsaIM71IdC+te3rCoVTOEVL2P9+FeqyrM3bx9\n" +
                "QInEvIxH1yUGPMrEnz2zxDCVQqASC89sQn5QvIkKkz2xJ7Ki3W0ojvfk9L/HGhaA\n" +
                "riCNsUwwpyZEa9XXRpxwUbilLOCF2JTVVb6jverp0QKBgEfYGmH/azXu5Nc2VpMb\n" +
                "TqLht8pVs/aSDTbLQoS5IrTtTrv+G54m3CADoSox7dMQgiJa5OH4hcmopbqBRBdd\n" +
                "z2vyE7Zaiua9qaKqvxSYFExwWDM80bFdVErhIceKW/UkZRDgeiORnMuJ3CJUPzml\n" +
                "M8wTM/mZ8CDNkXDf9686s32T";



        RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB.getValue(),privateKey,publicKey);

        String encrypt = rsa.encryptBase64("hello_world", KeyType.PublicKey);
        System.out.println(encrypt);

        String decrypt = rsa.decryptStr(encrypt, KeyType.PrivateKey);
        System.out.println(decrypt);

    }

}
